﻿using System;

namespace MugenInjection.Interface.Components
{
    /// <summary>
    /// Represent components of the <see cref="IInjector"/>.
    /// </summary>
    public interface IComponent : IDisposableObject
    {
        /// <summary>
        /// Gets the <see cref="IInjector"/> that owns the <see cref="IComponent"/>.
        /// </summary>
        IInjector Injector { get; }

        /// <summary>
        /// Indicates whether the component is unique.
        /// </summary>
        bool IsSingle { get; }

        /// <summary>
        /// Gets the component type. Need to find a component in the container.
        /// </summary>
        Type ComponentType { get; }

        /// <summary>
        /// Indicates that the component is loaded.
        /// </summary>
        bool IsLoaded { get; }

        /// <summary>
        /// Indicates that the component is now loading.
        /// </summary>
        bool IsLoading { get; }

        /// <summary>
        /// Indicates that the component is now unloading.
        /// </summary>
        bool IsUnloading { get; }

        /// <summary>
        /// Loads the current component to specified <see cref="IInjector"/>.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjector"/></param>
        void Load(IInjector injector);

        /// <summary>
        /// Loads the current component to specified <see cref="IInjector"/>.
        /// </summary>
        /// <param name="injector">The specified <see cref="IInjector"/></param>
        /// <param name="addToContainer">Indicates whether the component is automatically added to the <see cref="IComponentContainer"/>.</param>
        void Load(IInjector injector, bool addToContainer);

        /// <summary>
        /// Unloads the current component from <see cref="IInjector"/>.
        /// </summary>
        void Unload();

        /// <summary>
        /// Occured after loading current <see cref="IComponent"/>.
        /// </summary>
        event Action<IComponent> Loading;

        /// <summary>
        /// Occured after loaded current <see cref="IComponent"/>.
        /// </summary>
        event Action<IComponent> Loaded;

        /// <summary>
        /// Occured after unloading current <see cref="IComponent"/>.
        /// </summary>
        event Action<IComponent> Unloading;

        /// <summary>
        /// Occured after unloaded current <see cref="IComponent"/>.
        /// </summary>
        event Action<IComponent> Unloaded;

        /// <summary>
        /// Creates a new object that is a copy of the current instance.
        /// </summary>
        /// <returns>
        /// A new object that is a copy of this instance.
        /// </returns>
        IComponent Clone();
    }
}